package pl.icn.hurtownia.dao;

import java.math.BigDecimal;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import pl.icn.hurtownia.encje.Adres;
import pl.icn.hurtownia.encje.Klient;
import pl.icn.hurtownia.encje.Produkt;
import pl.icn.hurtownia.utils.HibernateUtil;

/**
 * DAO dla hurtowni
 */
public class HurtowniaDAO {
	
	/**
	 * Klienci, którzy mają:<br>
	 * - nazwisko na literę 'z'<br>
	 * - wypełniony numer telefonu<br>
	 * - adres e-mail na gmailu
	 */
	@SuppressWarnings("unchecked")
	public static List<Klient> zadanie1() {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		List<Klient> klienci = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Klient.class);
			cr.add(Restrictions.ilike("nazwisko", "z%"));
			cr.add(Restrictions.isNotNull("telefon"));
	        cr.add(Restrictions.ilike("email", "%@gmail.com"));
	        klienci = cr.list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace(); 
		} finally {
			session.close(); 
		}
		
		return klienci;
	}
	
	/**
	 * Klienci, które mają:<br>
	 * - cenę w przedziale od 2000 do 3000<br>
	 * - vat różny od 7%<br>
	 * (posortowani alfabetycznie po nazwie)
	 */
	@SuppressWarnings("unchecked")
	public static List<Produkt> zadanie2() {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		List<Produkt> produkty = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Produkt.class);
			cr.add(Restrictions.between("cena", new BigDecimal(2000), new BigDecimal(3000)));
			cr.add(Restrictions.ne("vat", 7));
			cr.addOrder(Order.asc("nazwa"));
	        produkty = cr.list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace(); 
		} finally {
			session.close(); 
		}
		
		return produkty;
	}
	
	/**
	 * Adresy z ulicy Słowackiego we Wrocławiu oraz z ulicy Mickiewicza w Krakowie
	 */
	@SuppressWarnings("unchecked")
	public static List<Adres> zadanie3() {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		List<Adres> adresy = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Adres.class);
			cr.add(Restrictions.or(
					Restrictions.and(Restrictions.eq("ulica", "Słowackiego"),
									Restrictions.eq("miasto", "Wrocław")),
					Restrictions.and(Restrictions.eq("ulica", "Mickiewicza"),
									Restrictions.eq("miasto", "Kraków"))
					));
	        adresy = cr.list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace(); 
		} finally {
			session.close(); 
		}
		
		return adresy;
	}
	
	/**
	 * Liczba unikalnych imion klientów
	 */
	public static Long zadanie4() {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		Long ilosc = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Klient.class);
			cr.setProjection(Projections.countDistinct("imie"));
	        ilosc = (Long) cr.uniqueResult();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace(); 
		} finally {
			session.close(); 
		}
		
		return ilosc;
	}
	
	/**
	 * Średnia cena produków, których vat wynosi co najmniej 10%
	 */
	public static BigDecimal zadanie5() {
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		BigDecimal srednia = null;
		try {
			tx = session.beginTransaction();
			Criteria cr = session.createCriteria(Produkt.class);
			cr.add(Restrictions.ge("vat", 10));
			cr.setProjection(Projections.avg("cena"));
	        srednia = (BigDecimal) cr.uniqueResult();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace(); 
		} finally {
			session.close(); 
		}
		
		return srednia;
	}
	
}
